package com.stars.easyms.swagger.constant;

import com.stars.easyms.base.annotation.EasyMsSwaggerModelProperty;
import com.stars.easyms.base.bean.UserInfo;
import com.stars.easyms.base.util.ApplicationContextHolder;
import com.stars.easyms.base.util.ConverterUtil;
import com.stars.easyms.rest.initializer.EasyMsRestInitializer;
import com.stars.easyms.rest.properties.EasyMsRestProperties;
import org.apache.commons.lang3.ClassUtils;
import org.apache.commons.lang3.StringUtils;

import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;

/**
 * <p>className: EasyMsSwaggerConstants</p>
 * <p>description: EasyMsSwagger常量类</p>
 *
 * @author guoguifang
 * @date 2019-11-25 17:52
 * @since 1.4.1
 */
public final class EasyMsSwaggerConstants {

    public static final String MODULE_NAME = "swagger";

    public static final String INDEX_URI = "/swagger";

    public static final String SWAGGER_RESOURCE = "/swagger-resources";

    public static final String API_DOCS = "/v2/api-docs";

    private static final Map<String, Map<String, Object>> RESPONSE_FOR_SWAGGER_MAP = new LinkedHashMap<>();

    private static Map<String, Map<String, Object>> userInfoForSwaggerMap;

    static {
        RESPONSE_FOR_SWAGGER_MAP.computeIfAbsent("success", s -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("type", "boolean");
            map.put("required", "true");
            map.put("description", "是否成功");
            map.put("example", true);
            return map;
        });
        RESPONSE_FOR_SWAGGER_MAP.computeIfAbsent("retCode", s -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("type", "string");
            map.put("required", "true");
            map.put("description", "返回编码(0000为成功，其他为失败)");
            map.put("example", "0000");
            return map;
        });
        RESPONSE_FOR_SWAGGER_MAP.computeIfAbsent("retMsg", s -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("type", "string");
            map.put("required", "false");
            map.put("description", "前端展示信息(成功时为null)");
            map.put("example", null);
            return map;
        });
        RESPONSE_FOR_SWAGGER_MAP.computeIfAbsent("errorDesc", s -> {
            Map<String, Object> map = new HashMap<>(8);
            map.put("type", "string");
            map.put("required", "false");
            map.put("description", "详细错误描述(成功时为null)");
            map.put("example", null);
            return map;
        });
    }

    public static Map<String, Map<String, Object>> getResponseForSwaggerMap() {
        return RESPONSE_FOR_SWAGGER_MAP;
    }

    public static Map<String, Map<String, Object>> getUserInfoForSwaggerMap() {
        if (userInfoForSwaggerMap == null) {
            userInfoForSwaggerMap = new LinkedHashMap<>();
            Class<?> userInfoClass = UserInfo.class;
            EasyMsRestProperties easyMsRestProperties = ApplicationContextHolder.getBean(EasyMsRestProperties.class);
            if (easyMsRestProperties != null) {
                String userInfoClassName = easyMsRestProperties.getUserInfoClass();
                if (StringUtils.isNotBlank(userInfoClassName)) {
                    try {
                        userInfoClass = ClassUtils.getClass(EasyMsRestInitializer.class.getClassLoader(), userInfoClassName);
                    } catch (ClassNotFoundException e) {
                        // ignore
                    }
                }
            }
            Field[] fields = userInfoClass.getDeclaredFields();
            for (Field field : fields) {
                if (field.isAnnotationPresent(EasyMsSwaggerModelProperty.class)) {
                    EasyMsSwaggerModelProperty modelProperty = field.getDeclaredAnnotation(EasyMsSwaggerModelProperty.class);
                    userInfoForSwaggerMap.computeIfAbsent(field.getName(), s -> {
                        Map<String, Object> map = new HashMap<>(8);
                        map.put("type", modelProperty.type());
                        map.put("required", modelProperty.required());
                        map.put("description", modelProperty.description());
                        map.put("example", ConverterUtil.cast(modelProperty.example(), field.getType()));
                        return map;
                    });
                }
            }
        }
        return userInfoForSwaggerMap;
    }

    private EasyMsSwaggerConstants() {
    }
}